﻿/*
 * KLF Headless Browser
 * Written by Kris Oye <kristianoye@gmail.com>
 * Copyright (C) 2011-2012.  All rights reserved.
 */
namespace KLF.Lib.Browser
{
    #region Using Statements

    using System;
    using System.Net;
    using System.Linq;
    using KLF.Lib.Browser.DOM;
    using KLF.Lib.Browser.DOM.HTML;
    using KLF.Lib.Browser.Resources;
    using System.Collections.Generic;
    using KLF.Lib.Browser.DOM.View;
    using KLF.Lib.Browser.JavascriptHelpers;

    #endregion

    /// <summary>
    /// Simulates a browser window or tab in a modern browser.  Keeps track
    /// of the browser history and exceptions encountered during browsing.
    /// </summary>
    public class BrowserWindow : IAbstractView, IDocumentView
    {
        #region Constructors

        internal BrowserWindow(WebBrowser owner)
        {
            Owner = owner;
            Errors = new List<Exception>();
            History = new History(this);
        }

        #endregion

        #region Properties

        /// <summary>
        /// The document loaded into the window.
        /// </summary>
        public Document ActiveDocument { get; set; }

        /// <summary>
        /// The current user credentials used for accessing pages.
        /// </summary>
        public ICredentials Credentials { get; set; }

        /// <summary>
        /// All errors that have occurred over the life of this window.
        /// </summary>
        public List<Exception> Errors { get; set; }

        /// <summary>
        /// This window's browse history.
        /// </summary>
        public History History { get; set; }

        /// <summary>
        /// The last error that occurred.
        /// </summary>
        public Exception LastError { get; protected set; }

        /// <summary>
        /// The location Uri that resulted in the currently loaded document.
        /// </summary>
        public Uri Location { get; set; }

        /// <summary>
        /// The browser this window belongs to.
        /// </summary>
        public WebBrowser Owner { get; protected set; }

        #endregion

        #region Methods

        /// <summary>
        /// Returns a list of anchors from the current document.
        /// </summary>
        public IEnumerable<HTMLAnchorElement> Anchors
        {
            get
            {
                return ActiveDocument
                    .Elements
                    .Where(e => e is HTMLAnchorElement)
                    .Cast<HTMLAnchorElement>();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public virtual bool ExecuteRequest(RequestContext context)
        {
            bool result = false;

            try
            {
                DocumentLoader loader = new DocumentLoader(context);
                ActiveDocument = loader.Load();
                result = true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error in ExecuteRequest(): {0}", ex.Message);
                result = false;
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public bool GoTo(RequestContext context)
        {
            context.Verb = HTMLConstants.HTTP_VERB_GET;
            return ExecuteRequest(context);
        }

        public bool GoTo(Uri uri)
        {
            return GoTo(new RequestContext(this, uri));
        }

        public bool GoTo(string url)
        {
            return GoTo(new Uri(url));
        }

        /// <summary>
        /// Returns a list of image elements from the current document.
        /// </summary>
        public IEnumerable<HTMLImageElement> Images
        {
            get
            {
                return ActiveDocument
                    .Elements
                    .Where(e => e.TagName.Equals(HTMLConstants.HTML_TAG_ANCHOR))
                    .Cast<HTMLImageElement>();
            }
        }

        #endregion

        #region IAbstractView Members

        public IDocumentView document
        {
            get { return ActiveDocument; }
        }

        #endregion

        #region IDocumentView Members

        public IAbstractView defaultView
        {
            get { return this; }
        }

        #endregion
    }
}
